Imports Clo = Enhancements.Core.Logging
Imports Ere = Enhancements.Basic.RegularExpressions
Imports Fun = Enhancements.Basic.Expressions.Functions
Imports Glo = System.Globalization
Imports Iou = System.IO
Imports Ref = System.Reflection
Imports Reg = System.Text.RegularExpressions
Imports Sys = System
Imports Tex = System.Text
Imports Val = Enhancements.Basic.Expressions.Values
Imports Xsd = System.Xml.Schema
Imports W3c = System.Xml

Namespace Enhancements.Basic.Expressions
    ''' <summary>Represents a variable within a compiled expression.</summary>
    <Serializable(), DebuggerStepThrough()> _
    Public NotInheritable Class ExpressionVariable

        ''' <exception cref="IsNullException"> </exception>
        Friend Sub New(ByVal _expression As Expression, ByVal _token As Variable)
            _expression.IsNullNot("_expression", True)
            _token.IsNullNot("_token", True)
            _token.Type.IsNullNot("_token.Type", True)

            __Expression = _expression
            Name = _token.ExpressionPart
            If _token.Type.Is("_token.Type", GetType(Val.Boolean), "GetType(Val.Boolean)", False) Then
                Type = GetType(Val.Boolean)
                UnderlyingType = Val.Boolean.UnderlyingType
            End If
            If _token.Type.Is("_token.Type", GetType(Val.DateTime), "GetType(Val.DateTime)", False) Then
                Type = GetType(Val.DateTime)
                UnderlyingType = Val.DateTime.UnderlyingType
            End If
            If _token.Type.Is("_token.Type", GetType(Val.Decimal), "GetType(Val.Decimal)", False) Then
                Type = GetType(Val.Decimal)
                UnderlyingType = Val.Decimal.UnderlyingType
            End If
            If _token.Type.Is("_token.Type", GetType(Val.Integer), "GetType(Val.Integer)", False) Then
                Type = GetType(Val.Integer)
                UnderlyingType = Val.Integer.UnderlyingType
            End If
            If _token.Type.Is("_token.Type", GetType(Val.String), "GetType(Val.String)", False) Then
                Type = GetType(Val.String)
                UnderlyingType = Val.String.UnderlyingType
            End If
            __Value = Nothing
        End Sub

        Private __Expression As Expression = Nothing

        Private __Name As System.String = Nothing
        ''' <summary>Gets the name of the variable.</summary>
        Public Property Name() As System.String
            Get
                Return __Name
            End Get
            Private Set(ByVal _value As System.String)
                __Name = _value
            End Set
        End Property

        Private __Type As System.Type = Nothing
        ''' <summary>Gets the type of the variable.</summary>
        Public Property Type() As System.Type
            Get
                Return __Type
            End Get
            Private Set(ByVal _value As System.Type)
                __Type = _value
            End Set
        End Property

        Private __UnderlyingType As System.Type = Nothing
        ''' <summary>Gets the associated framework type used for the token value storage.</summary>
        Public Property UnderlyingType() As System.Type
            Get
                Return __UnderlyingType
            End Get
            Private Set(ByVal _value As System.Type)
                __UnderlyingType = _value
            End Set
        End Property

        Private __Value As System.Object = Nothing
        ''' <summary>Gets and sets the value of the variable.</summary>
        ''' <exception cref="ExpressionVariableValueIsValidNotException">_value is not valid.</exception>
        Public Property Value() As System.Object
            Get
                Return __Value
            End Get
            Set(ByVal _value As System.Object)
                If Assert.IsNull(_value, "Value._value", False) Then
                    ExpressionVariableValueIsValidNotException.___Throw(__Expression, Me, _value)
                Else
                    If Val.Value.___AssertIsValidTypeAndValue(Type, _value).IsTrueNot("Val.Value.___AssertIsValidTypeAndValue(Type, _value)", False) Then
                        ExpressionVariableValueIsValidNotException.___Throw(__Expression, Me, _value)
                    End If
                End If

                __Value = _value
            End Set
        End Property

    End Class
End Namespace
